import json
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import UserWorkoutHistory, WorkoutPlan,WorkoutPlanExercise,Exercise
from user.models import User
from tools.report_builder import ConcreteWorkoutPlanBuilder,WorkoutPlanExercise
from report.serializer import ExerciseSerializer,WorkoutPlanSerializer,WorkoutPlanExerciseSerializer
from tools.plan_agents import executor, DatabaseWriter, PlanParser
from pydantic import ValidationError



# Create your views here.


class GeneralAgentView(APIView):
    """通用智能体接口 - 优化版，包含数据库写入功能"""

    def post(self, request):
        try:
            # 检查是否是白名单路径（如/report/general_agent）
            current_path = request.path.rstrip('/')
            whitelist_paths = ['/report/general_agent']
            
            user_info = None
            user = None
            
            # 如果是白名单路径，尝试从token获取用户信息，但不强制要求
            if current_path in whitelist_paths:
                print(f"🔍 白名单路径 {current_path}，尝试获取用户信息但不强制要求")
                
                # 尝试从中间件设置的user_info中获取用户信息
                user_info = getattr(request, 'user_info', None)
                
                if user_info:
                    print(f"✅ 白名单路径获取到用户信息: {user_info}")
                    try:
                        user = User.objects.get(id=user_info['user_id'])
                        print(f"✅ 成功获取用户对象: {user.username}")
                    except User.DoesNotExist:
                        print(f"⚠️ 用户不存在，将使用匿名模式")
                        user = None
                else:
                    print(f"ℹ️ 白名单路径未获取到用户信息，将使用匿名模式")
                    user = None
            else:
                # 非白名单路径，强制要求用户信息
                user_info = getattr(request, 'user_info', None)
                if not user_info:
                    return Response(
                        {"error": "请先登录后再使用此功能"},
                        status=status.HTTP_401_UNAUTHORIZED
                    )
                
                try:
                    user = User.objects.get(id=user_info['user_id'])
                except User.DoesNotExist:
                    return Response(
                        {"error": "用户不存在"},
                        status=status.HTTP_404_NOT_FOUND
                    )
            
            goals = request.data.get('goals', '')
            fitness_level = request.data.get('fitness_level', 'intermediate')
            duration = request.data.get('duration', 30)
            preferences = request.data.get('preferences', '')
            is_regenerate = request.data.get('is_regenerate', False)  # 新增：是否为重新生成

            if not goals:
                return Response(
                    {"error": "请提供训练目标"},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # 调用executor
            print(f"调用AI智能体，参数: goals={goals}, fitness_level={fitness_level}, duration={duration}, preferences={preferences}")

            # 准备executor参数
            executor_params = {
                "goals": goals,
                "fitness_level": fitness_level,
                "duration": duration,
                "preferences": preferences
            }
            
            # 如果有用户信息，添加用户ID以便AI分析训练历史
            if user:
                executor_params["user_id"] = user.id
                print(f"✅ 添加用户ID: {user.id}，AI将分析用户训练历史")
            else:
                print(f"ℹ️ 匿名用户，AI将使用通用推荐")

            try:
                res = executor.invoke(executor_params)
            except ValidationError as e:
                # 处理验证错误
                import logging
                logger = logging.getLogger(__name__)
                logger.error(f"Validation error: {e}")
                return Response(
                    {"error": "模型响应验证失败", "details": str(e)},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
            except Exception as e:
                # 处理其他LLM调用错误
                import logging
                logger = logging.getLogger(__name__)
                logger.error(f"LLM call failed: {e}")
                return Response(
                    {"error": "AI模型调用失败", "details": str(e)},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )

            # 解析AI回复的计划
            ai_response = res.get('output', '')
            print(f"AI响应: {ai_response}")

            # 解析AI响应
            plan_data = PlanParser.parse_ai_plan(ai_response)

            # 保存到数据库（如果有用户信息）
            workout_plan = None
            if user:
                if is_regenerate:
                    # 重新生成：查找并更新现有计划
                    try:
                        existing_plan = WorkoutPlan.objects.filter(
                            created_by=user,
                            title__icontains='AI生成'
                        ).order_by('-created_at').first()
                        
                        if existing_plan:
                            # 更新现有计划
                            print(f"🔄 更新现有AI训练计划: {existing_plan.id}")
                            existing_plan.title = plan_data.get('title', 'AI生成健身计划')
                            existing_plan.description = plan_data.get('description', '')
                            existing_plan.difficulty = plan_data.get('difficulty', 'intermediate')
                            existing_plan.total_duration = plan_data.get('total_duration', 0)
                            existing_plan.rest_time = plan_data.get('rest_time', 30)
                            existing_plan.save()
                            
                            # 清除旧的关联动作
                            existing_plan.exercises.clear()
                            
                            # 添加新的关联动作
                            exercises = plan_data.get('exercises', [])
                            for i, exercise_name in enumerate(exercises):
                                try:
                                    exercise = Exercise.objects.get(name=exercise_name)
                                    WorkoutPlanExercise.objects.create(
                                        workout_plan=existing_plan,
                                        exercise=exercise,
                                        sets=3,  # 默认值
                                        reps=10,  # 默认值
                                        order=i
                                    )
                                except Exercise.DoesNotExist:
                                    print(f"⚠️ 动作 {exercise_name} 不存在，跳过")
                            
                            workout_plan = existing_plan
                            print(f"✅ 成功更新AI训练计划: {workout_plan.id}")
                        else:
                            # 没有现有计划，创建新计划
                            workout_plan = DatabaseWriter.save_workout_plan_to_db(user, plan_data)
                            print(f"✅ 成功创建AI训练计划: {workout_plan.id}")
                    except Exception as e:
                        print(f"❌ 更新训练计划失败: {e}")
                        # 如果更新失败，尝试创建新计划
                        workout_plan = DatabaseWriter.save_workout_plan_to_db(user, plan_data)
                        print(f"✅ 更新失败，创建新计划: {workout_plan.id}")
                else:
                    # 正常生成：创建新计划
                    workout_plan = DatabaseWriter.save_workout_plan_to_db(user, plan_data)
                    print(f"✅ 计划已保存到数据库，计划ID: {workout_plan.id}")
            else:
                print(f"ℹ️ 匿名用户，计划未保存到数据库")

            # 准备响应数据
            response_data = {
                "success": True,
                "response": ai_response,
                "is_ai_generated": True,
                "message": "计划已成功生成"
            }
            
            # 如果有保存的计划，添加到响应中
            if workout_plan:
                serializer = WorkoutPlanSerializer(workout_plan)
                if is_regenerate:
                    response_data.update({
                        "saved_plan": serializer.data,
                        "plan_id": workout_plan.id,
                        "message": "训练计划重新生成并更新成功"
                    })
                else:
                    response_data.update({
                        "saved_plan": serializer.data,
                        "plan_id": workout_plan.id,
                        "message": "计划已成功生成并保存到数据库"
                    })
            else:
                response_data.update({
                    "message": "计划已成功生成（匿名模式，未保存到数据库）"
                })
            
            print(f"返回响应数据，响应长度: {len(ai_response)}")
            return Response(response_data)

        except Exception as e:
            import traceback
            error_traceback = traceback.format_exc()
            print(f"智能体执行错误详情: {error_traceback}")
            return Response(
                {"error": f"智能体执行失败: {str(e)}"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class UserWorkoutPlanView(APIView):
    """用户训练计划管理接口"""
    
    def get(self, request):
        """获取用户最近一次生成的AI训练计划"""
        try:
            # 检查是否是白名单路径
            current_path = request.path.rstrip('/')
            whitelist_paths = ['/report/user-workout-plan']
            
            user_info = None
            user = None
            
            # 如果是白名单路径，尝试从token获取用户信息，但不强制要求
            if current_path in whitelist_paths:
                print(f"🔍 白名单路径 {current_path}，尝试获取用户信息但不强制要求")
                
                # 尝试从中间件设置的user_info中获取用户信息
                user_info = getattr(request, 'user_info', None)
                
                if user_info:
                    print(f"✅ 白名单路径获取到用户信息: {user_info}")
                    try:
                        user = User.objects.get(id=user_info['user_id'])
                        print(f"✅ 成功获取用户对象: {user.username}")
                    except User.DoesNotExist:
                        print(f"⚠️ 用户不存在")
                        return Response(
                            {"error": "用户不存在"},
                            status=status.HTTP_404_NOT_FOUND
                        )
                else:
                    print(f"ℹ️ 白名单路径未获取到用户信息")
                    return Response(
                        {"error": "请先登录后再使用此功能"},
                        status=status.HTTP_401_UNAUTHORIZED
                    )
            else:
                # 非白名单路径，强制要求用户信息
                user_info = getattr(request, 'user_info', None)
                if not user_info:
                    return Response(
                        {"error": "请先登录后再使用此功能"},
                        status=status.HTTP_401_UNAUTHORIZED
                    )
                
                try:
                    user = User.objects.get(id=user_info['user_id'])
                except User.DoesNotExist:
                    return Response(
                        {"error": "用户不存在"},
                        status=status.HTTP_404_NOT_FOUND
                    )
            
            # 查询用户最近一次生成的AI训练计划
            try:
                latest_plan = WorkoutPlan.objects.filter(
                    created_by=user,
                    title__icontains='AI生成'  # 只查询AI生成的计划
                ).order_by('-created_at').first()
                
                if latest_plan:
                    print(f"✅ 找到用户最近一次AI训练计划: {latest_plan.id}")
                    serializer = WorkoutPlanSerializer(latest_plan)
                    return Response({
                        "success": True,
                        "has_plan": True,
                        "plan": serializer.data,
                        "message": "获取最近一次AI训练计划成功"
                    })
                else:
                    print(f"ℹ️ 用户 {user.username} 暂无AI训练计划")
                    return Response({
                        "success": True,
                        "has_plan": False,
                        "message": "您还没有生成过AI训练计划"
                    })
                    
            except Exception as e:
                print(f"❌ 查询用户训练计划失败: {e}")
                return Response(
                    {"error": "查询训练计划失败"},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
                
        except Exception as e:
            import traceback
            error_traceback = traceback.format_exc()
            print(f"获取用户训练计划错误详情: {error_traceback}")
            return Response(
                {"error": f"获取用户训练计划失败: {str(e)}"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
